package com.mingqijia.gassafety.authority.dal.handler;

import com.mingqijia.gassafety.authority.api.req.config.*;
import com.mingqijia.gassafety.authority.api.resp.config.DictionaryItemRespDTO;
import com.mingqijia.gassafety.authority.api.resp.config.DictionaryRespDTO;
import com.mingqijia.gassafety.authority.api.resp.config.ParamConfigRespDTO;
import com.mingqijia.gassafety.authority.api.resp.resource.OperationRespDTO;
import com.mingqijia.gassafety.authority.dal.command.*;
import com.mingqijia.gassafety.db.entity.auth.DictionaryItemEntry;
import com.mingqijia.gassafety.db.entity.auth.ParamConfigEntry;
import com.mingqijia.gassafety.shared.utils.MappingTools;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;

import java.util.Collections;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * 对象转换接口
 * @author Damon S.
 * @version v1.0.1
 * @date 2020年01月09日 20:37
 */
@Mapper(componentModel = "spring", uses = MappingTools.class)
@ConditionalOnMissingBean(ConfigureTranslatorImpl.class)
public interface ConfigureTranslator {

    @Mapping(source = "id", target = "paramId")
    ParamConfigRespDTO toRespDTO(ParamConfigEntry entry);

    DictionaryRespDTO toDictRespDTO(ParamConfigEntry entry);

    ParamConfigEntry toEntry(CreateParamConfigCommand command);

    ParamConfigEntry toEntry(UpdateParamConfigCommand command);

    ParamConfigEntry toEntry(RemoveParamConfigCommand command);

    @Mapping(source = "name", target = "alias")
    DictionaryItemEntry toEntry(CreateDictionaryItemCommand command);

    @Mapping(source = "name", target = "alias")
    DictionaryItemEntry toEntry(UpdateDictionaryItemCommand command);
    
    DictionaryItemEntry toEntry(RemoveDictionaryItemCommand command);

    @Mapping(source = "alias", target = "name")
    DictionaryItemRespDTO toItemRespDTO(DictionaryItemEntry entry);

    OperationRespDTO toRespDTO(DictionaryItemRespDTO resp);

    QueryParamConfigCommand toCommand(QueryParamConfigReqDTO req);

    QueryParamConfigCommand toCommand(QueryDictionaryReqDTO req);

    CreateParamConfigCommand toCommand(CreateParamConfigReqDTO req);

    CreateParamConfigCommand toCommand(CreateDictionaryReqDTO req);

    @Mapping(source = "code", target = "dictCode")
    CreateDictionaryItemCommand toCommand(CreateDictionaryItemReqDTO req);

    UpdateParamConfigCommand toCommand(UpdateParamConfigReqDTO req);

    UpdateParamConfigCommand toCommand(UpdateDictionaryReqDTO req);

    UpdateDictionaryItemCommand toCommand(UpdateDictionaryItemReqDTO req);

    RemoveParamConfigCommand toCommand(RemoveParamConfigReqDTO req);

    default List<ParamConfigRespDTO> toRespDTO(List<ParamConfigEntry> entries) {
        return Optional.ofNullable(entries)
                .orElse(Collections.emptyList())
                .stream().map(this::toRespDTO)
                .collect(Collectors.toList());
    }

    default List<DictionaryRespDTO> toDictRespDTO(List<ParamConfigEntry> entries) {
        return Optional.ofNullable(entries)
                .orElse(Collections.emptyList())
                .stream().map(this::toDictRespDTO)
                .collect(Collectors.toList());
    }

    default List<DictionaryItemRespDTO> toItemRespDTO(List<DictionaryItemEntry> entries) {
        return Optional.ofNullable(entries)
                .orElse(Collections.emptyList())
                .stream().map(this::toItemRespDTO)
                .collect(Collectors.toList());
    }

    default List<OperationRespDTO> toOpRespDTO(List<DictionaryItemRespDTO> resps) {
        return Optional.ofNullable(resps)
                .orElse(Collections.emptyList())
                .stream().map(this::toRespDTO)
                .collect(Collectors.toList());
    }
}
